package com.linln.admin.config;


import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.apache.commons.codec.digest.DigestUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

/**
 * 签名
 */
public class SignUtils {

    private static final Logger log = LoggerFactory.getLogger(SignUtils.class);

    private static Gson gson = new GsonBuilder().create();

    /**
     * 增加认证机制的方法
     */
    public static String toSign(Object obj, String devKey) {

        String content = "";

        if (obj instanceof String) {
            content = (String) obj;
        } else {
            if (obj != null) {
                content = gson.toJson(obj);

            }
        }

        String toSign = content + "&" + devKey;
        String md5Str = DigestUtils.md5Hex(toSign);

        return md5Str;
    }

    public static boolean isValidRequest(String sign, Object body,String devKey, String requestMethod) {

        if ("POST".equals(requestMethod)) {
            return isValidPostRequest(sign, body,devKey);
        }

        if ("GET".equals(requestMethod)) {
            return isValidGetRequest(sign, (String) body, devKey);
        }

        // todo 其他请求：PUT DELETE
//        return isValidPostRequest(sign, body, devId, devKey, pushTime);
        return true;

    }

    /**
     * POST 请求校验
     *
     * @param sign     签名
     * @param body     body
     * @param devKey
     * @return
     */
    public static boolean isValidPostRequest(String sign, Object body, String devKey) {
        return isValidSign(sign, body,devKey);
    }

    /**
     * POST 请求校验
     *
     * @param sign     签名
     * @param url      url
     * @param devKey
     * @return
     */
    public static boolean isValidGetRequest(String sign, String url,String devKey) {

        //fixme  url是否需要解码

        String content = "";
        try {
            url = URLDecoder.decode(url, "UTF-8");
            content = getUrlParams(url);
        } catch (Exception e) {
            e.printStackTrace();
            log.info("签名认证失败：sign={},url={}", sign, url);
        }
        return isValidSign(sign, content,devKey);
    }

    /**
     * 校验
     *
     * @param sign     签名
     * @param content  内容
     * @param devKey   开发者key
     * @return
     */
    private static boolean isValidSign(String sign, Object content, String devKey) {

        //1.鉴权
        String sysSign = toSign(content, devKey);
        return sysSign.equals(sign);
    }

    /**
     * GET请求
     * 对url的参数进行加密
     * 例如：url = xxx?a=1&b=2  =>拿a=1&b=2&出来
     *
     * @param url
     * @param devKey
     * @return
     */
    public static String toSignUrl(String url, String devKey) {
        String content = "";
        try {
            content = getUrlParams(url);
        } catch (Exception e) {

        }
        return toSign(content, devKey);
    }

    /**
     * 将url参数转换成map
     *
     * @param url www.baidu.com?aa=11&bb=22&cc=33
     * @return
     */
    private static String getUrlParams(String url) throws Exception {

        StringBuffer queryString = new StringBuffer();
        url = url.replace("?", ";");
        if (!url.contains(";")) {
            return url;
        }

        if (url.split(";").length > 0) {
            String[] arr = url.split(";")[1].split("&");

            for (int i = 0; i < arr.length; i++) {
                String[] values = arr[i].split("=");
                String key = values[0];
                String value = values[1];

                queryString.append(key + "=");
                queryString.append(URLEncoder.encode(value, "UTF-8"));
                if (i != (arr.length - 1)) {
                    queryString.append("&");
                }
            }
        }

        return queryString.toString();
    }

    /**
     * 推送时间 秒级别
     *
     * @return
     */
    public static Integer getPushTime() {
        Long now = (System.currentTimeMillis() / 1000);
        return now.intValue();
    }

    public static Integer getTime(Long time) {
        Long now = (time / 1000);
        return now.intValue();
    }


    public static Map<String, String> getGetHeader(String url, String appKey) {
        String signUrl = SignUtils.toSignUrl(url, appKey);
        return getHeader(signUrl);
    }

    /**
     * @param content body 请求体
     * @return
     */
    public static Map<String, String> getPostHeader(Object content, String appKey) {
        String sign = SignUtils.toSign(content, appKey);
        return getHeader(sign);
    }

    private static Map<String, String> getHeader(String sign) {
        Map<String, String> header = new HashMap<String, String>();
        header.put("timestamp", System.currentTimeMillis() / 1000 + "");
        header.put("sign", sign);
        return header;
    }
}
